//
//  WDCalendarDateHandler.m
//  Demos
//
//  Created by iMac on 2018/3/2.
//  Copyright © 2018年 iMac. All rights reserved.
//

#import "WDCalendarDateHandler.h"
#import "WDCalendarDayModel.h"




@implementation WDCalendarDateHandler

+ (instancetype)sharedInstance {
    static WDCalendarDateHandler *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[WDCalendarDateHandler alloc] init];
    });
    return instance;
}
/// 通过当前页的日期, 获取上一月,本月,下一月 WDCalendarDayModel 集合数组的 集合
- (NSArray *)dataForCalendar:(NSDate *)currentPageDate {
    NSDate *dateInLastMonth = [self dateForLastMonth:currentPageDate];
    NSDate *dateInNextMonth = [self dateForNextMonth:currentPageDate];
    NSMutableArray *marr = [NSMutableArray array];
    [marr addObject:[self daysInPage:dateInLastMonth]];
    [marr addObject:[self daysInPage:currentPageDate]];
    [marr addObject:[self daysInPage:dateInNextMonth]];
    
    return [marr copy];
}
/// 通过当前页的Date获取当前月所有的WDCalendarDayModel集合
- (NSArray *)daysInPage:(NSDate *)date {
    NSArray *dates = [self datesOfCurrentCalendarPage:date];
    NSMutableArray *marr = [NSMutableArray array];
    for (int i = 0; i < dates.count; i++) {
        NSDate *date = dates[i];
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy-MM-dd";
        // NSLog(@"date: -- %@", [formatter stringFromDate:date]);
        WDCalendarDayModel *model = [[WDCalendarDayModel alloc] init];
        model.date = date;
        [marr addObject:model];
    }
    return [marr copy];
}

// 获取日历有几行
- (NSInteger)numsOfRows:(NSDate *)date {
    NSInteger days = [self dayCountInThisMonth:date];
    NSInteger rankInWeek = [self dayOfWeekInThisMonth:date];
    NSInteger rows = (days + rankInWeek - 1) / 7;
    if (((days + rankInWeek - 1) % 7) != 0) {
        rows += 1;
    }
    return rows;
}

// 获取当前日历页的所有数据 NSArray<NSDate>
- (NSArray *)datesOfCurrentCalendarPage:(NSDate *)date {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    
    NSMutableArray *mArray = [NSMutableArray array];
    if ([self dayOfWeekInThisMonth:date] > 1) {
        if ([components month] == 1) {
            components.month = 12;
            components.year = components.year - 1;
        }
        else {
            components.month = components.month - 1;
        }
        NSDate *lastMonthDate = [calendar dateFromComponents:components];
        components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:lastMonthDate];
        NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:lastMonthDate];
        NSInteger rankInWeek = [self dayOfWeekInThisMonth:date];
        
        for (int i = 1; i < rankInWeek; i++) {
            components.day = range.length - (rankInWeek - 1 - i);
            NSDate *targetDate = [calendar dateFromComponents:components];
            [mArray addObject:targetDate];
        }
    }
    components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    components.day = 1;
    NSRange currentMonthRange = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
    for (int i = 0; i < currentMonthRange.length; i++) {
        NSDate *targetDatea = [calendar dateFromComponents:components];
        [mArray addObject:targetDatea];
        components.day += 1;
    }
    NSInteger days = [self dayCountInThisMonth:date];
    NSInteger rankInWeek = [self dayOfWeekInThisMonth:date];
    if (((days + rankInWeek - 1) % 7) != 0) {
        if (components.month == 12) {
            components.year += 1;
            components.month = 1;
            components.day = 1;
        }
        else {
            components.month += 1;
            components.day = 1;
        }
        for (int i = 0; i < (days + rankInWeek - 1) % 7; i++) {
            NSDate *targetDate = [calendar dateFromComponents:components];
            [mArray addObject:targetDate];
            components.day += 1;
        }
    }
    return mArray.copy;
}

// 返回上个月的1号的date
- (NSDate *)dateForLastMonth:(NSDate *)date {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    if ([components month] == 1) {
        components.year -= 1;
        components.month = 12;
    }
    else {
        components.month -= 1;
    }
    components.day = 1;
    return [calendar dateFromComponents:components];
}
// 返回下个月的1号的date
- (NSDate *)dateForNextMonth:(NSDate *)date {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    NSDateComponents *comp = [[NSDateComponents alloc] init];
    if (components.month == 12) {
        [comp setYear:components.year + 1];
        [comp setMonth:1];
        [comp setDay:2];
    }
    else {
        [comp setYear:components.year];
        [comp setMonth:components.month + 1];
        [comp setDay:2];
    }
    NSLog(@"components %@: ", comp);
    NSLog(@"dateForNextMonth date: %@", date);
    NSLog(@"[calendar dateFromComponents:components]: %@", [calendar dateFromComponents:comp]);
    
    return [calendar dateFromComponents:comp];
}


- (NSInteger)dayOfWeekInThisMonth:(NSDate *)date {
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *comps = [cal components:NSCalendarUnitYear | NSCalendarUnitMonth fromDate:date];
    comps.day = 1;
    NSDate *firstDay = [cal dateFromComponents:comps];
    comps = [cal components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitWeekday fromDate:firstDay];
    return [comps weekday];
}

- (NSInteger)dayCountInThisMonth:(NSDate *)date {
    NSCalendar * calendar = [NSCalendar currentCalendar];
    NSInteger monthNum = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length;
    return monthNum;
}










@end
